﻿using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.Runtime;
using System;
using System.Linq;
namespace cad
{
    public class StretchType
    {

        // 拉伸操作方法
        public void StretchSelection(ObjectIdCollection selectedIds, Point3d basePoint, double distance,
         double leftBoundary, double rightBoundary, double topBoundary, double bottomBoundary)
        {
            Document doc = Application.DocumentManager.MdiActiveDocument;
            Database db = doc.Database;
            Editor ed = doc.Editor;

            foreach (ObjectId objId in selectedIds)
            {
                using (Transaction trans = Application.DocumentManager.MdiActiveDocument.TransactionManager.StartTransaction())
                {
                    Entity entity = (Entity)trans.GetObject(objId, OpenMode.ForWrite);


                    // 对于 Line 类型的实体
                    //if (entity is Line line)
                    //{
                    //    Point3d startPoint = line.StartPoint;
                    //    Point3d endPoint = line.EndPoint;

                    //    // 判断起点和终点是否在新生成的矩形内
                    //    bool isStartInside = startPoint.X >= leftBoundary && startPoint.X <= rightBoundary &&
                    //                         startPoint.Y >= bottomBoundary && startPoint.Y <= topBoundary;
                    //    bool isEndInside = endPoint.X >= leftBoundary && endPoint.X <= rightBoundary &&
                    //                       endPoint.Y >= bottomBoundary && endPoint.Y <= topBoundary;

                    //    if (isStartInside && isEndInside)
                    //    {
                    //        // 完全包含在框选区域内，移动起始点和终止点
                    //        line.StartPoint = new Point3d(startPoint.X + distance, startPoint.Y, startPoint.Z);
                    //        line.EndPoint = new Point3d(endPoint.X + distance, endPoint.Y, endPoint.Z);
                    //    }
                    //    else
                    //    {
                    //        // 线段与框选区域相交，只移动起始点和交点
                    //        if (isStartInside)
                    //        {
                    //            line.StartPoint = new Point3d(startPoint.X + distance, startPoint.Y, startPoint.Z);
                    //        }

                    //        if (isEndInside)
                    //        {
                    //            line.EndPoint = new Point3d(endPoint.X + distance, endPoint.Y, endPoint.Z);
                    //        }
                    //    }
                    //}
                    if (entity is Line line)
                    {
                        Point3d startPoint = line.StartPoint;
                        Point3d endPoint = line.EndPoint;

                        // 判断起点是否在框选区域内
                        bool isStartInside = startPoint.X >= leftBoundary && startPoint.X <= rightBoundary &&
                                             startPoint.Y >= bottomBoundary && startPoint.Y <= topBoundary;

                        // 判断终点是否在框选区域内
                        bool isEndInside = endPoint.X >= leftBoundary && endPoint.X <= rightBoundary &&
                                           endPoint.Y >= bottomBoundary && endPoint.Y <= topBoundary;

                        // 如果起点在框选区域内，移动起点
                        if (isStartInside)
                        {
                            line.StartPoint = new Point3d(startPoint.X + distance, startPoint.Y, startPoint.Z);
                        }

                        // 如果终点在框选区域内，移动终点
                        if (isEndInside)
                        {
                            line.EndPoint = new Point3d(endPoint.X + distance, endPoint.Y, endPoint.Z);
                        }
                    }

                    else if (entity is Spline spline)
                    {
                        // 获取并更新 Spline 的控制点
                        int controlPointCount = spline.NumControlPoints;

                        for (int i = 0; i < controlPointCount; i++)
                        {
                            Point3d controlPoint = spline.GetControlPointAt(i);

                            // 判断控制点是否在框选区域内
                            bool isControlPointInside = controlPoint.X >= leftBoundary && controlPoint.X <= rightBoundary &&
                                                        controlPoint.Y >= bottomBoundary && controlPoint.Y <= topBoundary;

                            if (isControlPointInside)
                            {
                                // 如果控制点在框选区域内，更新控制点位置
                                spline.SetControlPointAt(i, new Point3d(controlPoint.X + distance, controlPoint.Y, controlPoint.Z));
                            }
                        }

                        // 更新样条曲线的形状
                        spline.Rebuild(spline.Degree, spline.NumControlPoints);  // 使用 Rebuild 方法来更新样条曲线
                    }




                    // 对于 多行文字类型的实体（包括虚线等多段线）
                    else if (entity is MText mtext)

                    {

                        Point3d textPosition = mtext.Location;
                        bool isTextPositionInside = textPosition.X >= leftBoundary && textPosition.X <= rightBoundary &&
                                                        textPosition.Y >= bottomBoundary && textPosition.Y <= topBoundary;
                        if (isTextPositionInside)
                        {
                            // 更新 MText 的位置
                            mtext.Location = new Point3d(textPosition.X + distance, textPosition.Y, textPosition.Z);
                        }
                       
                       
                    }

                   
                    // 对于 Polyline2D\3D 类型的实体（包括虚线等多段线）
                    else if (entity is Polyline2d polyline2d || entity is Polyline3d polyline3d)
                    {
                        Polyline pl = new Polyline();

                        // 判断类型，如果是 Polyline2d 或者 Polyline3d，转换为 Polyline
                        if (entity is Polyline2d)
                        {
                            pl.ConvertFrom((Polyline2d)entity, false);
                        }
                        else if (entity is Polyline3d)
                        {
                            pl.ConvertFrom((Polyline3d)entity, false);
                        }

                        // 获取 Polyline 顶点数量
                        int numVertices = pl.NumberOfVertices;

                        // 使用新的事务变量名称，避免与外部变量冲突
                        using (Transaction trans2 = db.TransactionManager.StartTransaction())
                        {
                            BlockTable blockTable = (BlockTable)trans2.GetObject(db.BlockTableId, OpenMode.ForRead);
                            BlockTableRecord modelSpace = (BlockTableRecord)trans2.GetObject(blockTable[BlockTableRecord.ModelSpace], OpenMode.ForWrite);

                            Entity polylineEntity = (Entity)trans2.GetObject(entity.ObjectId, OpenMode.ForWrite);

                            // 删除对象
                            polylineEntity.Erase();

                            // 遍历 Polyline 顶点并修改
                            for (int i = 0; i < numVertices; i++)
                            {
                                // 获取当前顶点的坐标
                                Point3d pt = pl.GetPoint3dAt(i);

                                // 判断该点是否在框选区域内
                                bool isPointInside = pt.X >= leftBoundary && pt.X <= rightBoundary &&
                                                     pt.Y >= bottomBoundary && pt.Y <= topBoundary;

                                if (isPointInside)
                                {
                                    // 如果该点在框选区域内，移动该点
                                    Point2d newPoint2d = new Point2d(pt.X + distance, pt.Y);  // 将 Point3d 转为 Point2d

                                    // 更新顶点，使用 Point2d 类型
                                    pl.SetPointAt(i, newPoint2d);  // 使用 Point2d 作为参数
                                }
                            }

                            // 将更新后的 Polyline 对象重新放入模型中（如果需要）
                            modelSpace.AppendEntity(pl);
                            trans2.AddNewlyCreatedDBObject(pl, true);

                            // 提交事务
                            trans2.Commit();
                        }
                    }



                    // 对于 Polyline 类型的实体（包括虚线等多段线）
                    else if (entity is Polyline polyline)
                    {
                        // 获取 Polyline 顶点数量
                        int numVertices = polyline.NumberOfVertices;

                        // 遍历 Polyline 顶点并修改
                        for (int i = 0; i < numVertices; i++)
                        {
                            // 获取当前顶点的坐标
                            Point3d pt = polyline.GetPoint3dAt(i);

                            // 判断该点是否在框选区域内
                            bool isPointInside = pt.X >= leftBoundary && pt.X <= rightBoundary &&
                                                 pt.Y >= bottomBoundary && pt.Y <= topBoundary;

                            if (isPointInside)
                            {
                                // 如果该点在框选区域内，移动该点
                                Point2d newPoint2d = new Point2d(pt.X + distance, pt.Y);  // 将 Point3d 转为 Point2d

                                // 更新顶点，使用 Point2d 类型
                                polyline.SetPointAt(i, newPoint2d);  // 使用 Point2d 作为参数
                            }
                        }
                    }


                    // 对于 Arc 类型的实体
                    else if (entity is Arc arc)
                    {
                        // 判断圆心是否在框选区域内
                        Point3d center = arc.Center;
                        bool isCenterInside = center.X >= leftBoundary && center.X <= rightBoundary &&
                                              center.Y >= bottomBoundary && center.Y <= topBoundary;

                        if (isCenterInside)
                        {
                            // 如果圆心在框选区域内，平移圆心
                            arc.Center = new Point3d(center.X + distance, center.Y, center.Z);
                        }
                    }

                    // 对于 Circle 类型的实体（圆形）
                    else if (entity is Circle circle)
                    {
                        // 判断圆心是否在框选区域内
                        Point3d center = circle.Center;
                        bool isCenterInside = center.X >= leftBoundary && center.X <= rightBoundary &&
                                              center.Y >= bottomBoundary && center.Y <= topBoundary;

                        if (isCenterInside)
                        {
                            // 如果圆心在框选区域内，平移圆心
                            circle.Center = new Point3d(center.X + distance, center.Y, center.Z);
                        }
                    }


                    // 对于 Linear Dimension（线性标注）类型的实体
                    else if (entity is AlignedDimension alignedDimension)
                    {
                        // 获取线性标注的起点和终点
                        Point3d startPoint = alignedDimension.XLine1Point;
                        Point3d endPoint = alignedDimension.XLine2Point;

                        // 判断起点和终点是否在框选区域内
                        bool isStartInside = startPoint.X >= leftBoundary && startPoint.X <= rightBoundary &&
                                             startPoint.Y >= bottomBoundary && startPoint.Y <= topBoundary;
                        bool isEndInside = endPoint.X >= leftBoundary && endPoint.X <= rightBoundary &&
                                           endPoint.Y >= bottomBoundary && endPoint.Y <= topBoundary;

                        // 如果起点和终点都在框选区域内，移动两点
                        if (isStartInside && isEndInside)
                        {
                            alignedDimension.XLine1Point = new Point3d(startPoint.X + distance, startPoint.Y, startPoint.Z);
                            alignedDimension.XLine2Point = new Point3d(endPoint.X + distance, endPoint.Y, endPoint.Z);
                        }
                        else
                        {
                            // 如果起点在框选区域内，移动起点
                            if (isStartInside)
                            {
                                alignedDimension.XLine1Point = new Point3d(startPoint.X + distance, startPoint.Y, startPoint.Z);
                            }

                            // 如果终点在框选区域内，移动终点
                            if (isEndInside)
                            {
                                alignedDimension.XLine2Point = new Point3d(endPoint.X + distance, endPoint.Y, endPoint.Z);
                            }
                        }
                    }
                    else if (entity is RotatedDimension angularDim)
                    {
                        // 获取线性标注的起点、终点和文本控制点
                        Point3d startPoint = angularDim.XLine1Point;
                        Point3d endPoint = angularDim.XLine2Point;
                        Point3d textPoint = angularDim.TextPosition;

                        // 提取原始 Y 坐标值，固定在 Y 轴上
                        double originalY = textPoint.Y;

                        // 判断起点和终点的 X 坐标是否相同，判断是否是竖向标注
                        bool isVertical = startPoint.X == endPoint.X;

                        // 判断起点、终点和文本是否在框选区域内
                        bool isStartInside = startPoint.X >= leftBoundary && startPoint.X <= rightBoundary &&
                                             startPoint.Y >= bottomBoundary && startPoint.Y <= topBoundary;
                        bool isEndInside = endPoint.X >= leftBoundary && endPoint.X <= rightBoundary &&
                                           endPoint.Y >= bottomBoundary && endPoint.Y <= topBoundary;
                        bool isTextInside = textPoint.X >= leftBoundary && textPoint.X <= rightBoundary &&
                                            textPoint.Y >= bottomBoundary && textPoint.Y <= topBoundary;

                        if (isVertical)
                        {
                            // 处理竖向标注
                            if (isStartInside && isEndInside)
                            {
                                // 竖向标注只更新 Y 坐标
                                angularDim.XLine1Point = new Point3d(startPoint.X + distance, startPoint.Y, startPoint.Z);
                                angularDim.XLine2Point = new Point3d(endPoint.X + distance, endPoint.Y, endPoint.Z);

                                // 更新文本位置，保持 Y 坐标不变
                                angularDim.TextPosition = new Point3d(textPoint.X + distance, originalY, textPoint.Z);
                            }
                            else
                            {
                                // 如果起点在框选区域内，移动起点并更新文本位置
                                if (isStartInside && !isEndInside)
                                {
                                    angularDim.XLine1Point = new Point3d(startPoint.X + distance, startPoint.Y, startPoint.Z);

                                    // 更新文本位置，保持 Y 坐标不变
                                    angularDim.TextPosition = new Point3d(textPoint.X + distance / 2, originalY, textPoint.Z);
                                }

                                // 如果终点在框选区域内，移动终点并更新文本位置
                                if (isEndInside && !isStartInside)
                                {
                                    angularDim.XLine2Point = new Point3d(endPoint.X + distance, endPoint.Y, endPoint.Z);

                                    // 更新文本位置，保持 Y 坐标不变
                                    angularDim.TextPosition = new Point3d(textPoint.X + distance / 2, originalY, textPoint.Z);
                                }
                            }
                        }
                        else
                        {
                            // 处理水平标注和其他类型标注
                            if (isStartInside && isEndInside)
                            {
                                angularDim.XLine1Point = new Point3d(startPoint.X + distance, startPoint.Y, startPoint.Z);
                                angularDim.XLine2Point = new Point3d(endPoint.X + distance, endPoint.Y, endPoint.Z);

                               
                            }
                            else
                            {
                                // 如果起点在框选区域内，移动起点并更新文本位置
                                if (isStartInside && !isEndInside)
                                {
                                    angularDim.XLine1Point = new Point3d(startPoint.X + distance, startPoint.Y, startPoint.Z);

                                   
                                }

                                // 如果终点在框选区域内，移动终点并更新文本位置
                                if (isEndInside && !isStartInside)
                                {
                                    angularDim.XLine2Point = new Point3d(endPoint.X + distance, endPoint.Y, endPoint.Z);

                                                                 
                                }
                            }
                        }

                    }


                    else if (entity is MLeader mLeader)
                    {
                        

                        // 获取并更新 MLeader 的引线位置
                        for (int i = 0; i < mLeader.LeaderCount; i++)
                        {
                            // 获取引线的第一个点（起点）和最后一个点（终点）
                            Point3d leaderStart = mLeader.GetFirstVertex(i);
                            Point3d leaderEnd = mLeader.GetLastVertex(i);

                            // 判断第一个点是否在框选区域内
                            bool isLeaderStartInside = leaderStart.X >= leftBoundary && leaderStart.X <= rightBoundary &&
                                                       leaderStart.Y >= bottomBoundary && leaderStart.Y <= topBoundary;

                            if (isLeaderStartInside)
                            {
                                // 如果第一个点在框选区域内，移动所有引线的顶点和文本
                                int vertexCount = mLeader.VerticesCount(i);
                                for (int j = 0; j < vertexCount; j++)
                                {
                                    Point3d leaderVertex = mLeader.GetVertex(i, j);
                                    mLeader.SetVertex(i, j, new Point3d(leaderVertex.X + distance, leaderVertex.Y, leaderVertex.Z));
                                }

                             
                            }
                        }
                    }





                    trans.Commit();
                }

            }
        }
    }
}
